<?php
namespace app\api\service;

use app\exceptions\OrdinaryException;

/**
 * OAuth2 Service
 * User: zng
 * Date: 2019/10/15
 * Time: 16:00
 */
Class OAuth2{

    /**
     * 第三方登录配置数组
     * @var array
     */
    private $_secerts;

    /**
     * 第三方登录配置名
     * @var array
     */
    private $_secretKeys;

    /**
     * 第三方登录APPID
     * @var string
     */
    private $_appId;

    /**
     * 第三方登录秘钥
     * @var string
     */
    private $_secret;

    /**
     * 授权类型
     * @var string
     */
    private $_grant_type;

    /**
     * 请求地址
     * @var string
     */
    private $_request_uri;

    public function __construct()
    {
        $this->_secerts = config('secret.');
        $this->_secretKeys = array_keys($this->_secerts);
    }

    /**
     * 第三方用户信息操作
     * @param string $code code码,用来换取access_token
     * @param string $state 来源
     * @author zx
     * @date 2019-10-21
     * @throw OrdinaryException
     * @return array
     */
    public function handler(string $code, string $state):array
    {
        if ( !$code || !$state || !in_array($state, $this->_secretKeys) )
            throw new OrdinaryException('非法请求!');

        //判断配置是否填写
        if (!isset($this->_secerts[$state]['appid']) ||
            !$this->_secerts[$state]['appid'] ||
            !isset($this->_secerts[$state]['secret']) ||
            !$this->_secerts[$state]['secret'] ||
            !isset($this->_secerts[$state]['grant_type']) ||
            !$this->_secerts[$state]['grant_type'] ||
            !isset($this->_secerts[$state]['uri']['request_uri']) ||
            !$this->_secerts[$state]['uri']['request_uri'])
            throw new OrdinaryException('服务器配置错误');

        //初始化参数
        $this->_appId = $this->_secerts[$state]['appid']??NULL;
        $this->_secret = $this->_secerts[$state]['secret']??NULL;
        $this->_grant_type = $this->_secerts[$state]['grant_type']??NULL;
        $this->_request_uri = $this->_secerts[$state]['uri']['request_uri']??NULL;

        $func = $state.'_third_info';
        $data = $this->$func($code);

        if ( !$data )
            throw new OrdinaryException('auth_failed', 500);

        return $data;
    }

    /**
     * 微信小程序获取第三方ID
     * @param string $code code码
     * @author zx
     * @date 2019-10-21
     * return array
     */
    private function xcx_third_info(string $code):array
    {
        $params['appid'] = $this->_appId;
        $params['secret'] = $this->_secret;
        $params['js_code'] = $code;
        $params['grant_type'] = $this->_grant_type;
        $url = $this->_request_uri.'?'.http_build_query($params);

        $request_data = json_decode(curl_req($url), true);
        if ( ! $request_data['openid'] )
            throw new OrdinaryException($request_data['errmsg']);

        return $request_data;
    }

}